use crate::models::articles::{CreateParams, Model};
use axum::debug_handler;
use loco_rs::prelude::*;

#[debug_handler]
async fn create(
    State(ctx): State<AppContext>,
    Json(params): Json<CreateParams>,
) -> Result<Response> {
    let article = Model::create(&ctx.db, &params).await?;
    format::json(article)
}

#[debug_handler]
async fn find_by_id(State(ctx): State<AppContext>, Path(id): Path<String>) -> Result<Response> {
    let article = Model::find_by_id(&ctx.db, &id).await?;
    format::json(article)
}

#[debug_handler]
async fn find_by_slug(State(ctx): State<AppContext>, Path(slug): Path<String>) -> Result<Response> {
    let article = Model::find_by_slug(&ctx.db, &slug).await?;
    format::json(article)
}

#[debug_handler]
async fn find_by_catalog_id(
    State(ctx): State<AppContext>,
    Path(status): Path<String>,
) -> Result<Response> {
    let articles = Model::find_by_catalog_id(&ctx.db, &status).await?;
    format::json(articles)
}

#[debug_handler]
async fn update_status(
    State(ctx): State<AppContext>,
    Path(id): Path<String>,
    Json(status): Json<bool>,
) -> Result<Response> {
    let article = Model::find_by_id(&ctx.db, &id).await?;
    let article = article
        .into_active_model()
        .update_active_status(&ctx.db, status)
        .await?;
    format::json(article)
}

#[debug_handler]
async fn delete_by_id(State(ctx): State<AppContext>, Path(id): Path<String>) -> Result<Response> {
    let article = Model::find_by_id(&ctx.db, &id).await?;
    article.delete(&ctx.db).await?;
    format::json(())
}

pub fn routes() -> Routes {
    Routes::new()
        .prefix("articles")
        .add("/", post(create))
        .add("/:id", get(find_by_id))
        .add("/slug/:slug", get(find_by_slug))
        .add("/status/:status", get(find_by_catalog_id))
        .add("/:id/status", put(update_status))
        .add("/:id", delete(delete_by_id))
}
